package cn.huaqingcheng.tianshu.infrastructure.uc.repository;

import cn.huaqingcheng.tianshu.core.uc.model.Account;
import cn.huaqingcheng.tianshu.core.uc.repository.AccountRepository;
import cn.huaqingcheng.tianshu.infrastructure.uc.UcConvert;
import cn.huaqingcheng.tianshu.infrastructure.uc.entity.AccountEntity;
import cn.huaqingcheng.tianshu.infrastructure.uc.entity.AccountPasswordEntity;
import cn.huaqingcheng.tianshu.infrastructure.uc.mapper.AccountMapper;
import cn.huaqingcheng.tianshu.infrastructure.uc.mapper.AccountPasswordMapper;
import cn.huaqingcheng.tianshu.mybatis.OptimisticLockTool;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;

import java.util.Optional;

/**
 * AccountRepositoryImpl
 */
@Repository
@RequiredArgsConstructor
public class AccountRepositoryImpl implements AccountRepository {

    private final AccountMapper accountMapper;

    private final AccountPasswordMapper passwordMapper;


    @Override
    public Optional<Account> getByUsername(String username) {
        Optional<Account> account = new LambdaQueryChainWrapper<>(accountMapper)
                .eq(AccountEntity::getUsername, username)
                .oneOpt()
                .map(UcConvert.INSTANCE::toModel);

        return account.map(i -> {
            var password = new LambdaQueryChainWrapper<>(passwordMapper)
                    .eq(AccountPasswordEntity::getAccountId, i.getId())
                    .oneOpt()
                    .map(UcConvert.INSTANCE::toModel)
                    .orElseThrow();

            return i.setPassword(password);
        });
    }

    @Override
    public Optional<Account> getById(Long id) {
        return new LambdaQueryChainWrapper<>(accountMapper)
                .eq(AccountEntity::getId, id)
                .oneOpt()
                .map(UcConvert.INSTANCE::toModel);
    }

    @Override
    public Account updateById(Account account) {
        AccountEntity entity = UcConvert.INSTANCE.toEntity(account);
        int i = accountMapper.updateById(entity);
        OptimisticLockTool.assertion(i, account.getVersion());

        return UcConvert.INSTANCE.toModel(entity);
    }

}
